home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / 92052tar.gz / 920528.tar / alloc.c next >
C/C++ Source or Header  |  1992-05-28  |  6KB  |  256 lines

  1. /* @(#) $Header: alloc.c,v 1.12 92/05/28 13:50:01 deyke Exp $ */
  2.  
  3. /* memory allocation routines
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <unistd.h>
  10.  
  11. #include "global.h"
  12. #include "mbuf.h"
  13.  
  14. #define DEBUG           1
  15.  
  16. #define ALLOCSIZE       0x8000
  17. #define FREETABLESIZE   2048
  18. #define MEMFULL         ((struct block *) (-1))
  19. #define MINSIZE         16
  20. #define SBRK(i)         ((struct block *) sbrk((int) (i)))
  21.  
  22. struct block {
  23.   struct block *next;
  24. };
  25.  
  26. static struct block Freetable[FREETABLESIZE];
  27. static unsigned long Memfail;   /* Count of allocation failures */
  28. static unsigned long Allocs;    /* Total allocations */
  29. static unsigned long Frees;     /* Total frees */
  30. static unsigned long Invalid;   /* Total calls to free with garbage arg */
  31. static unsigned long Heapsize;
  32. static unsigned long Inuse;
  33. static unsigned long Morecores;
  34.  
  35. static void giveup __ARGS((char *mesg));
  36. static unsigned int blksize __ARGS((void *p));
  37.  
  38. /*---------------------------------------------------------------------------*/
  39.  
  40. static void giveup(mesg)
  41. char  *mesg;
  42. {
  43.   fprintf(stderr, mesg);
  44.   abort();
  45. }
  46.  
  47. /*---------------------------------------------------------------------------*/
  48.  
  49. void *malloc(size)
  50. register unsigned int  size;
  51. {
  52.  
  53.   static struct block *freespace;
  54.   static unsigned int  freesize;
  55.  
  56.   int  align_error;
  57.   register struct block *p, *tp;
  58.  
  59.   size = (size + sizeof(struct block *) + MINSIZE - 1) & ~(MINSIZE - 1);
  60.   if ((tp = Freetable + size / MINSIZE) >= Freetable + FREETABLESIZE)
  61.     giveup("malloc: requested block too large\n");
  62.   if (p = tp->next)
  63.     tp->next = p->next;
  64.   else {
  65.     if (size > freesize) {
  66.       if (freesize) {
  67.     struct block *tpf = Freetable + freesize / MINSIZE;
  68.     freespace->next = tpf->next;
  69.     tpf->next = freespace;
  70.     freesize = 0;
  71.       }
  72.       if ((freespace = SBRK(ALLOCSIZE)) == MEMFULL) {
  73.     Memfail++;
  74.     return 0;
  75.       }
  76.       Morecores++;
  77.       Heapsize += (freesize = ALLOCSIZE);
  78.       if (align_error = (MINSIZE - 1) & -(((int) freespace) + sizeof(struct block *))) {
  79.     freespace = (struct block *) (align_error + (int) freespace);
  80.     freesize -= MINSIZE;
  81.       }
  82.     }
  83.     p = freespace;
  84.     freespace += (size / sizeof(struct block *));
  85.     freesize -= size;
  86.   }
  87.   p->next = tp;
  88.   Allocs++;
  89.   Inuse += size;
  90.   return (void *) (p + 1);
  91. }
  92.  
  93. /*---------------------------------------------------------------------------*/
  94.  
  95. void *mallocw(size)
  96. unsigned int  size;
  97. {
  98.   return malloc(size);
  99. }
  100.  
  101. /*---------------------------------------------------------------------------*/
  102.  
  103. void *_malloc(size)
  104. unsigned int  size;
  105. {
  106.   return malloc(size);
  107. }
  108.  
  109. /*---------------------------------------------------------------------------*/
  110.  
  111. void free(pp)
  112. void *pp;
  113. {
  114.   register struct block *p, *tp;
  115.  
  116.   if (p = (struct block *) pp) {
  117.     if ((MINSIZE - 1) & (int) p) {
  118. #if DEBUG
  119.       giveup("free: bad alignment\n");
  120. #else
  121.       Invalid++;
  122.       return;
  123. #endif
  124.     }
  125.     p--;
  126.     tp = p->next;
  127.     if (tp < Freetable || tp >= Freetable + FREETABLESIZE) {
  128. #if DEBUG
  129.       giveup("free: bad free table pointer\n");
  130. #else
  131.       Invalid++;
  132.       return;
  133. #endif
  134.     }
  135.     Frees++;
  136.     Inuse -= (tp - Freetable) * MINSIZE;
  137.     p->next = tp->next;
  138.     tp->next = p;
  139.   }
  140. }
  141.  
  142. /*---------------------------------------------------------------------------*/
  143.  
  144. void _free(pp)
  145. void *pp;
  146. {
  147.   free(pp);
  148. }
  149.  
  150. /*---------------------------------------------------------------------------*/
  151.  
  152. /* Return size of allocated buffer, in bytes */
  153.  
  154. static unsigned int  blksize(p)
  155. void *p;
  156. {
  157.   register struct block *tp;
  158.  
  159.   tp = (struct block *) p;
  160.   tp--;
  161.   tp = tp->next;
  162.   return (tp - Freetable) * MINSIZE - sizeof(struct block *);
  163. }
  164.  
  165. /*---------------------------------------------------------------------------*/
  166.  
  167. void *realloc(p, size)
  168. void *p;
  169. unsigned int  size;
  170. {
  171.  
  172.   unsigned int  oldsize;
  173.   void *q;
  174.  
  175.   oldsize = blksize(p);
  176.   if (size <= oldsize) return p;
  177.   if (q = malloc(size)) {
  178.     memcpy(q, p, oldsize);
  179.     free(p);
  180.   }
  181.   return q;
  182. }
  183.  
  184. /*---------------------------------------------------------------------------*/
  185.  
  186. void *_realloc(p, size)
  187. void *p;
  188. unsigned int  size;
  189. {
  190.   return realloc(p, size);
  191. }
  192.  
  193. /*---------------------------------------------------------------------------*/
  194.  
  195. void *calloc(nelem, elsize)
  196. unsigned int  nelem, elsize;
  197. {
  198.  
  199.   register char  *q;
  200.   register unsigned int  size;
  201.   register void *p;
  202.  
  203.   if (p = malloc(size = nelem * elsize))
  204.     for (q = (char *) p;  size--; *q++ = '\0') ;
  205.   return p;
  206. }
  207.  
  208. /*---------------------------------------------------------------------------*/
  209.  
  210. void *callocw(nelem, elsize)
  211. unsigned int  nelem, elsize;
  212. {
  213.   return calloc(nelem, elsize);
  214. }
  215.  
  216. /*---------------------------------------------------------------------------*/
  217.  
  218. void *_calloc(nelem, elsize)
  219. unsigned int  nelem, elsize;
  220. {
  221.   return calloc(nelem, elsize);
  222. }
  223.  
  224. /*---------------------------------------------------------------------------*/
  225.  
  226. /* Return 0 if at least Memthresh memory is available. Return 1 if
  227.  * less than Memthresh but more than Memthresh/2 is available; i.e.,
  228.  * if a yellow garbage collection should be performed. Return 2 if
  229.  * less than Memthresh/2 is available, i.e., a red collection should
  230.  * be performed.
  231.  */
  232. int
  233. availmem()
  234. {
  235.         return 0;       /* We're clearly OK */
  236. }
  237.  
  238. /*---------------------------------------------------------------------------*/
  239.  
  240. /* Print heap stats */
  241. int domem(argc,argv,envp)
  242. int argc;
  243. char *argv[];
  244. void *envp;
  245. {
  246.     printf("heap size %lu avail %lu (%lu%%) morecores %lu\n",
  247.      Heapsize,Heapsize-Inuse,100L*(Heapsize-Inuse)/Heapsize,
  248.      Morecores);
  249.     printf("allocs %lu frees %lu (diff %lu) alloc fails %lu invalid frees %lu\n",
  250.         Allocs,Frees,Allocs-Frees,Memfail,Invalid);
  251.     printf("pushdown calls %lu pushdown calls to malloc %lu\n",
  252.         Pushdowns,Pushalloc);
  253.     return 0;
  254. }
  255.  
  256.